package cnpm.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import cnpm.controller.listener.SessionCounter;
import cnpm.dto.UserDTO;
import cnpm.entity.ConditionSearch;
import cnpm.entity.Contract;
import cnpm.entity.Department;
import cnpm.entity.Employee;
import cnpm.entity.Insurance;
import cnpm.entity.Office;
import cnpm.service.ConditionSearchService;
import cnpm.service.ContractService;
import cnpm.service.DepartmentService;
import cnpm.service.EmployeeService;
import cnpm.service.InsuranceService;
import cnpm.service.OfficeService;
import cnpm.service.UserService;

/**
 * Servlet implementation class EmployeeController
 */
@WebServlet("/EmployeeController.do")
public class EmployeeController extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public EmployeeController() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		request.setAttribute("counter", SessionCounter.getTotalActiveSession());
		RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/_view/_main.jsp");
		dispatcher.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		String action = request.getParameter("action");
		if(action.equals("getAll")){
			getAll(request, response);
		}else if(action.equals("search")){
			searchEmployee(request, response);
		}else if(action.equals("saveConditionSearch")){
			saveConditionSearch(request, response);
		}else if(action.equals("delete")){
			deleteEmployee(request, response);
		}
	}

	private void getAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String jsonEmployee = getAllEmployee();
		String jsonDepartment = getAllDepartment();
		String jsonOffice = getAllOffice();
		String jsonCondition = getAllCondition(request);
		response.getWriter().write(jsonEmployee+"~"+jsonDepartment+"~"+jsonOffice+"~"+jsonCondition);
	}
	
	private void searchEmployee(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		EmployeeService empS = (EmployeeService) context.getBean("employeeService");
		OfficeService officeS = (OfficeService) context.getBean("officeService");
		DepartmentService deptS = (DepartmentService) context.getBean("departmentService");
		
		String empFirstName = "";
		String empLastName = "";
		String empPhone = "";
		String empEmail = "";
		Department empDept = null;
		Office empOffice = null;
		
		if(Boolean.parseBoolean(request.getParameter("before"))){
			String condition = request.getParameter("condition");
			String[] conditions = condition.split("-");
			empFirstName = conditions[0];
			empLastName = conditions[1];
			empEmail = conditions[2];
			empPhone = conditions[3];
			empDept = deptS.getDepartmentByID(Integer.parseInt(conditions[4]));
			empOffice = officeS.getOffice(Integer.parseInt(conditions[5]));
		}else{
			empFirstName = request.getParameter("firstname");
			empLastName = request.getParameter("lastname");
			empPhone = request.getParameter("phone");
			empEmail = request.getParameter("email");
			empDept = deptS.getDepartmentByID(Integer.parseInt(request.getParameter("dept")));
			empOffice = officeS.getOffice(Integer.parseInt(request.getParameter("office")));
		}
		
		response.getWriter().print(convertListEmployeeToJson(empS
				.searchEmployee(empFirstName, empLastName, empPhone, empOffice, empEmail, empDept)));
	}
	
	public void saveConditionSearch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		UserService userS = (UserService) context.getBean("userService");
		ConditionSearchService conditionS = (ConditionSearchService) context.getBean("conditionSearchService");
		
		UserDTO user = (UserDTO) request.getSession().getAttribute("User");
		
		String firstName = request.getParameter("firstName");
		String lastName = request.getParameter("lastName");
		String email = request.getParameter("email");
		String phone = request.getParameter("phone");
		String department = request.getParameter("department");
		String office = request.getParameter("office");
		
		ConditionSearch condition = new ConditionSearch();
		condition.setName(request.getParameter("conditionName"));
		condition.setCondition(firstName+"-"+lastName+"-"+email+"-"+phone+"-"+department+"-"+office);
		condition.setUser(userS.getUser(user.getUsername()));
		
		if(conditionS.saveOrUpdateConditionSearch(condition)){
			response.getWriter().write("Save condtion search successfull~"+convertListConditionToJson(
					conditionS.getAllConditionSearch(userS.getUser(user.getUsername()))));
		}else{
			response.getWriter().write("Save condtion search not success~");
		}
	}
	
	private void deleteEmployee(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		EmployeeService empS = (EmployeeService) context.getBean("employeeService");
		ContractService contractS = (ContractService) context.getBean("contractService");
		InsuranceService insuranceS = (InsuranceService) context.getBean("insuranceService");
		
		boolean flag = false;
		int count = 0;
		String employeeID = request.getParameter("employeeID");
		String[] employeeIDs = employeeID.split("~");
		for(String empID: employeeIDs){
			if(!empID.equals("")){
				Employee employee = empS.getEmployeeByID(empID);
				List<Contract> contracts = contractS.getAllContract(employee);
				List<Insurance> insurances = insuranceS.getAllInsurance(employee);
				if(delete(contracts, insurances, employee)){
					flag = true;
					count++;
				}else{
					flag = false;
					break;
				}
			}
		}
		if(flag){
			response.getWriter().write("Delete employee successfull~"+String
					.valueOf(convertListEmployeeToJson(empS.getAllEmployee())));
		}else{
			response.getWriter().write("Delete employee "+count +"in "+employeeIDs.length+"~"+String
					.valueOf(convertListEmployeeToJson(empS.getAllEmployee())));
		}
	}
	
	public boolean delete(List<Contract> contracts, List<Insurance> insurances, Employee employee){
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		EmployeeService empS = (EmployeeService) context.getBean("employeeService");
		ContractService contractS = (ContractService) context.getBean("contractService");
		InsuranceService insuranceS = (InsuranceService) context.getBean("insuranceService");
		
		List<Contract> contractOlds = new ArrayList<Contract>();
		List<Insurance> insuranceOlds = new ArrayList<Insurance>();
		boolean contractFlag = false;
		boolean insuranceFlag = false;
		
		for (Contract contract : contracts) {
			if(contractS.deleteContract(contract)){
				contractFlag = true;
				contractOlds.add(contract);
			}else{
				contractFlag = false;
				for(Contract contractOld: contractOlds){ //Khôi phục lại những cái đã xóa
					contractS.saveOrUpdateContract(contractOld);
				}
				break;
			}
		}
		
		for(Insurance insurance: insurances){
			if(insuranceS.deleteInsurance(insurance)){
				insuranceFlag = true;
				insuranceOlds.add(insurance);
			}else{
				insuranceFlag = false;
				for(Insurance insuranceOld: insuranceOlds){
					insuranceS.saveOrUpdateInsurance(insuranceOld);
				}
				break;
			}
		}
		
		if(contractFlag || insuranceFlag|| contractFlag && insuranceFlag){
			if(empS.deleteEmployee(employee)){
				contractOlds = null;
				insuranceOlds = null;
				return true;
			}else{
				for(Contract contractOld: contractOlds){
					contractS.saveOrUpdateContract(contractOld);
				}
				for(Insurance insuranceOld: insuranceOlds){
					insuranceS.saveOrUpdateInsurance(insuranceOld);
				}
				return false;
			}
		} else if(!contractFlag && !insuranceFlag){
			if(empS.deleteEmployee(employee)){
				contractOlds = null;
				insuranceOlds = null;
				return true;
			}
		}
		return false;
	}
	
	public String getAllEmployee(){
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		EmployeeService empS = (EmployeeService) context.getBean("employeeService");
		return String.valueOf(convertListEmployeeToJson(empS.getAllEmployee()));
	}
	
	private String getAllOffice(){
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		OfficeService officeS = (OfficeService) context.getBean("officeService");
		return convertListOfficeToJson(officeS.getAllOffice());		
	}
	
	private String getAllDepartment(){
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		DepartmentService deptS = (DepartmentService) context.getBean("departmentService");
		return convertListDepartmentToJson(deptS.getAllDepartments());
	}
	
	private String getAllCondition(HttpServletRequest request)throws ServletException, IOException {
		ApplicationContext context = WebApplicationContextUtils
	            .getRequiredWebApplicationContext((getServletContext()));
		UserService userS = (UserService) context.getBean("userService");
		ConditionSearchService conditionS = (ConditionSearchService) context.getBean("conditionSearchService");
		
		UserDTO user = (UserDTO) request.getSession().getAttribute("User");
		return convertListConditionToJson(conditionS.getAllConditionSearch(userS.getUser(user.getUsername())));
	}
	private String convertListOfficeToJson(List<Office> offices){
		JsonObject jsonResponse = new JsonObject();
		JsonArray jsonArray = new JsonArray();
		JsonObject jsonObj;
		for(Office office: offices){
			jsonObj = new JsonObject();
			jsonObj.addProperty("OfficeID", office.getOfficeID());
			jsonObj.addProperty("OfficeName", office.getOfficeName());
			jsonArray.add(jsonObj);
		}
		jsonResponse.add("OfficeList", jsonArray);
		return String.valueOf(jsonResponse);
	}
	
	private String convertListDepartmentToJson(List<Department> departments){
		JsonObject jsonResponse = new JsonObject();
		JsonArray jsonArray = new JsonArray();
		JsonObject jsonObj;
		for(Department d: departments){
			jsonObj = new JsonObject();
			jsonObj.addProperty("DeptID", d.getDeptID());
			jsonObj.addProperty("DeptName", d.getDeptName());
			jsonArray.add(jsonObj);
		}
		jsonResponse.add("DeptList", jsonArray);
		return String.valueOf(jsonResponse);		
	}
	
	private String convertListConditionToJson(List<ConditionSearch> conditions){
		JsonObject jsonResponse = new JsonObject();
		JsonArray jsonArray = new JsonArray();
		JsonObject jsonObj;
		for(ConditionSearch condition: conditions){
			jsonObj = new JsonObject();
			jsonObj.addProperty("condition", condition.getCondition());
			jsonObj.addProperty("conditionName", condition.getName());
			jsonArray.add(jsonObj);
		}
		jsonResponse.add("ConditionList", jsonArray);
		return String.valueOf(jsonResponse);		
	}

	private JsonObject convertListEmployeeToJson(List<Employee> emplist){
		JsonObject jsonRespone = new JsonObject();
		JsonArray jsonArray = new JsonArray();
		JsonObject jsonObj;
		for(Employee e: emplist){
			jsonObj = new JsonObject();
			jsonObj.addProperty("EmpID", e.getEmployeeID());
			jsonObj.addProperty("FristName", e.getFirstName());
			jsonObj.addProperty("LastName", e.getLastName());
			jsonObj.addProperty("Department", e.getDepartment().getDeptName());
			jsonObj.addProperty("Office", e.getOffice().getOfficeName());
			jsonObj.addProperty("Phone", e.getPhone());
			jsonObj.addProperty("Email", e.getEmail());
			jsonArray.add(jsonObj);
		}
		jsonRespone.add("EmployeeList", jsonArray);
		return jsonRespone;
	}
}
